
#ifndef __SSH_TELESCOPE_H
#define __SSH_TELESCOPE_H

#include "../db/KeyDB.h"
#include "../db/NetworkDB.h"
#include "PersistentForwardChannel.h"
#include "SSHClient.h"
#include <vector>
#include <utility>
#include <string>

/** A class for automating the creation of SSH telescopes/forwarding
 * chains capable of firewall-punching to access hard to reach
 * resources. */
class SSHTelescope
{
   public:
      /** Flags for marking the links in order to find a quick best
       * route. */
      enum sshlinkmark  { LINKMARK_UNTESTED      = 0,
                          LINKMARK_TRIED         = (1 << 0),
                          LINKMARK_ESTABLISHED   = (1 << 1) };
      SSHTelescope(const char *iusername, NetworkDB &inetdb, KeyDB &ikeydb, const char *idst_host, const int idst_port, apr_pool_t *imp, const char *secretkeypwd);
      ~SSHTelescope();
      int getLocalPort();
      int telescopeOkay();
   protected:
      SSHClient *autoSSH(const char *remotehost, const int remoteport, const int localport, const char *secretkeypwd);
      int determineIfLocallyAccessible(const char *ihostname, const int iportno);
      std::vector<std::pair<std::pair<std::string, int>, int> > *sortByCommonSuffix(std::vector<char *> *unsorted_hosts, std::vector<int> *unsorted_ports, const char *destination);
      void buildTelescope(const char *secretkeypwd);
   private:
      /** The memory pool to be used for the class. */
      apr_pool_t *mp;
      /** The stack of SSH clients generating many SSH connections to
       * produce the telescope effect. */
      std::vector<SSHClient *> sshclients;
      /** The persistent forwarding channels which forward these
       * connection over each other. */
      std::vector<PersistentForwardChannel *> forwardings;
      /** Sets of blacklists, which tell the state of each of the
       * servers.  These are stacked so that if a server has no
       * access, access can be rolled back easily to the previous SSH
       * client connection. */
      std::vector<std::vector<std::pair<std::pair<std::string, int>, int> > *> blacklists;
      /** The network database pointer for querying network
       * beliefs. */
      NetworkDB *networkdb;
      /** The key database for looking up keys needed to access remote
       * resources. */
      KeyDB *keydb;
      /** The username of the delegated SSH actor ID. */
      char *username;
      /** The final destination host name (unique). */
      char *destination_host;
      /** The final destination host port. */
      int destination_port;
      /** Is the current telescope embodied by this class valid? */
      int telescopevalid;
      /** Final local port whose forwarding is the final hop of the
       * chain. */
      int final_local_forward;
};

#endif
